using AutoMapper;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ShopPowerTemplate.Entities;
using ShopPowerTemplate.IoC;
using ShopPowerTemplate.Presentation.Mvc.Controllers;
using ShopPowerTemplate.Presentation.Mvc.Extensions.BootStrapper;
using ShopPowerTemplate.Presentation.Mvc.ViewModels;
using ShopPowerTemplate.Services.Tests;
using System.Web.Mvc;

namespace ShopPowerTemplate.Presentation.Mvc.Test
{
    [TestClass]
    public class ProductControllerTestBase
    {
        [TestInitialize]
        public virtual void TestInitialize()
        {
            IBootStrapper bootStrapper = new DefaultBootStrapper(IoCFactory.Instance.CurrentContainer);
            bootStrapper.Boot();
        }

        [TestMethod]
        public virtual void ProductController_IndexTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());

            var result = controller.Index() as ViewResult;
            
            Assert.IsNotNull(result);
            //ViewName is empty when ViewResult matches action name
            Assert.IsTrue(string.IsNullOrEmpty(result.ViewName));
            Assert.IsTrue(result.Model is IndexProductViewModel);
        }

        [TestMethod]
        public virtual void ProductController_LoadTest()
        {
            ProductServiceUtil.CreateProduct();
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());

            var result = controller.Load("", "", 0, 10, "") as JsonResult;

            var rows = ModelHelper.GetList(result.Data);
            Assert.IsTrue(rows.Count > 0);
        }

        [TestMethod]
        public virtual void ProductController_DeleteTest()
        {
            Product product = ProductServiceUtil.CreateProduct();
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());

            var result = controller.Delete(product.Id) as ContentResult;

            Assert.IsNotNull(result);
            Assert.IsTrue(string.IsNullOrEmpty(result.Content));
        }

        [TestMethod]
        public virtual void ProductController_ReportTest()
        {
            Product product = ProductServiceUtil.CreateProduct();
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());

            var result = controller.Report() as FileContentResult;

            Assert.IsNotNull(result);
            Assert.IsTrue(result.ContentType == "text/csv");
            Assert.IsNotNull(result.FileContents.Length > 0);
        }

        [TestMethod]
        public virtual void ProductController_GetCreateTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());

            var result = controller.Create() as ViewResult;

            Assert.IsNotNull(result);
            //ViewName is empty when ViewResult matches action name
            Assert.IsTrue(string.IsNullOrEmpty(result.ViewName));
            Assert.IsTrue(result.Model is CreateProductViewModel);
        }

        [TestMethod]
        public virtual void ProductController_PostCreateTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            Product product = ProductServiceUtil.GetProduct();
            CreateProductViewModel viewModel = Mapper.Map<Product, CreateProductViewModel>(product);

            var result = controller.Create(viewModel) as RedirectToRouteResult;

            Assert.IsNotNull(result);
            Assert.AreEqual(result.RouteValues["action"], "Edit"); //Create redirect to edit action on success
            Assert.IsTrue((int)result.RouteValues["id"] > 0); //Check new item id
        }

        [TestMethod]
        public virtual void ProductController_GetEditTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            Product product = ProductServiceUtil.CreateProduct();

            var result = controller.Edit(product.Id) as ViewResult;

            Assert.IsNotNull(result);
            //ViewName is empty when ViewResult matches action name
            Assert.IsTrue(string.IsNullOrEmpty(result.ViewName));
            Assert.IsTrue(result.Model is EditProductViewModel);
            Assert.AreEqual((result.Model as EditProductViewModel).Name, product.Name);
        }

        [TestMethod]
        public virtual void ProductController_PostEditTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            Product product = ProductServiceUtil.CreateProduct();
            product.Name = "Test";

            EditProductViewModel viewModel = Mapper.Map<Product, EditProductViewModel>(product);
            controller.Edit(viewModel);

            var result = controller.Edit(product.Id) as ViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual((result.Model as EditProductViewModel).Name, "Test");
        }

        [TestMethod]
        public virtual void ProductController_DetailTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            Product product = ProductServiceUtil.CreateProduct();

            var result = controller.Details(product.Id) as ViewResult;

            Assert.IsNotNull(result);
            //ViewName is empty when ViewResult matches action name
            Assert.IsTrue(string.IsNullOrEmpty(result.ViewName));
            Assert.IsTrue(result.Model is DetailsProductViewModel);
            Assert.AreEqual((result.Model as DetailsProductViewModel).Name, product.Name);
        }

		/* Details region test */
        [TestMethod]
        public virtual void ProductController_LoadImagesTest()
        {
            Image images = ImageServiceUtil.CreateImageFull();
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());

            var result = controller.LoadImages("", "", 0, 10, "", 1, images.Product.Id) as JsonResult;

            var rows = ModelHelper.GetList(result.Data);
            Assert.IsTrue(rows.Count > 0);
        }
        
        [TestMethod]
        public virtual void ProductController_AddImagesTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            Image images = ImageServiceUtil.GetImageFull();
            PopUpImageViewModel viewModel = Mapper.Map<Image, PopUpImageViewModel>(images);

            var result = controller.AddImages(viewModel) as ContentResult;

            Assert.IsNotNull(result);
            Assert.AreEqual(result.Content, "OK");
        }

        [TestMethod]
        public virtual void ProductController_GetEditImagesTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            Image images = ImageServiceUtil.CreateImageFull();

            var result = controller.EditImages(images.Id, images.Product.Id) as PartialViewResult;

            Assert.IsNotNull(result);
            //ViewName is empty when ViewResult matches action name
            Assert.AreEqual(result.ViewName, "~/Views/Image/PopUp.cshtml");
            Assert.IsTrue(result.Model is PopUpImageViewModel);
			Assert.AreEqual((result.Model as PopUpImageViewModel).Name, images.Name);
            
        }

        [TestMethod]
        public virtual void ProductController_PostEditImagesTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            Image images = ImageServiceUtil.CreateImageFull();
            images.Name = "Test";

            PopUpImageViewModel viewModel = Mapper.Map<Image, PopUpImageViewModel>(images);
            controller.EditImages(viewModel);

            var result = controller.EditImages(images.Id) as PartialViewResult;
            Assert.IsNotNull(result);
			Assert.AreEqual((result.Model as PopUpImageViewModel).Name, "Test");
        }

        [TestMethod]
        public virtual void ProductController_DeleteImagesTest()
        {
            Image images = ImageServiceUtil.CreateImageFull();
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());

            controller.DeleteImages(images.Id, images.Product.Id);

            Assert.AreEqual(controller.Response.StatusCode, 200);
        }

		/* Details region test */
        [TestMethod]
        public virtual void ProductController_LoadReviewsTest()
        {
            Review reviews = ReviewServiceUtil.CreateReviewFull();
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());

            var result = controller.LoadReviews("", "", 0, 10, "", 1, reviews.Product.Id) as JsonResult;

            var rows = ModelHelper.GetList(result.Data);
            Assert.IsTrue(rows.Count > 0);
        }
        
        [TestMethod]
        public virtual void ProductController_AddReviewsTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            Review reviews = ReviewServiceUtil.GetReviewFull();
            PopUpReviewViewModel viewModel = Mapper.Map<Review, PopUpReviewViewModel>(reviews);

            var result = controller.AddReviews(viewModel) as ContentResult;

            Assert.IsNotNull(result);
            Assert.AreEqual(result.Content, "OK");
        }

        [TestMethod]
        public virtual void ProductController_GetEditReviewsTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            Review reviews = ReviewServiceUtil.CreateReviewFull();

            var result = controller.EditReviews(reviews.Id, reviews.Product.Id) as PartialViewResult;

            Assert.IsNotNull(result);
            //ViewName is empty when ViewResult matches action name
            Assert.AreEqual(result.ViewName, "~/Views/Review/PopUp.cshtml");
            Assert.IsTrue(result.Model is PopUpReviewViewModel);
			Assert.AreEqual((result.Model as PopUpReviewViewModel).Comment, reviews.Comment);
            
        }

        [TestMethod]
        public virtual void ProductController_PostEditReviewsTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            Review reviews = ReviewServiceUtil.CreateReviewFull();
            reviews.Comment = "Test";

            PopUpReviewViewModel viewModel = Mapper.Map<Review, PopUpReviewViewModel>(reviews);
            controller.EditReviews(viewModel);

            var result = controller.EditReviews(reviews.Id) as PartialViewResult;
            Assert.IsNotNull(result);
			Assert.AreEqual((result.Model as PopUpReviewViewModel).Comment, "Test");
        }

        [TestMethod]
        public virtual void ProductController_DeleteReviewsTest()
        {
            Review reviews = ReviewServiceUtil.CreateReviewFull();
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());

            controller.DeleteReviews(reviews.Id, reviews.Product.Id);

            Assert.AreEqual(controller.Response.StatusCode, 200);
        }

		/* Details region test */
        [TestMethod]
        public virtual void ProductController_LoadProductDetailsTest()
        {
            ProductDetail productDetails = ProductDetailServiceUtil.CreateProductDetailFull();
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());

            var result = controller.LoadProductDetails("", "", 0, 10, "", 1, productDetails.Product.Id) as JsonResult;

            var rows = ModelHelper.GetList(result.Data);
            Assert.IsTrue(rows.Count > 0);
        }
        
        [TestMethod]
        public virtual void ProductController_AddProductDetailsTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            ProductDetail productDetails = ProductDetailServiceUtil.GetProductDetailFull();
            PopUpProductDetailViewModel viewModel = Mapper.Map<ProductDetail, PopUpProductDetailViewModel>(productDetails);

            var result = controller.AddProductDetails(viewModel) as ContentResult;

            Assert.IsNotNull(result);
            Assert.AreEqual(result.Content, "OK");
        }

        [TestMethod]
        public virtual void ProductController_GetEditProductDetailsTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            ProductDetail productDetails = ProductDetailServiceUtil.CreateProductDetailFull();

            var result = controller.EditProductDetails(productDetails.Id, productDetails.Product.Id) as PartialViewResult;

            Assert.IsNotNull(result);
            //ViewName is empty when ViewResult matches action name
            Assert.AreEqual(result.ViewName, "~/Views/ProductDetail/PopUp.cshtml");
            Assert.IsTrue(result.Model is PopUpProductDetailViewModel);
			Assert.AreEqual((result.Model as PopUpProductDetailViewModel).Stock, productDetails.Stock);
            
        }

        [TestMethod]
        public virtual void ProductController_PostEditProductDetailsTest()
        {
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());
            ProductDetail productDetails = ProductDetailServiceUtil.CreateProductDetailFull();
            productDetails.Stock = 1;

            PopUpProductDetailViewModel viewModel = Mapper.Map<ProductDetail, PopUpProductDetailViewModel>(productDetails);
            controller.EditProductDetails(viewModel);

            var result = controller.EditProductDetails(productDetails.Id) as PartialViewResult;
            Assert.IsNotNull(result);
			Assert.AreEqual((result.Model as PopUpProductDetailViewModel).Stock, 1);
        }

        [TestMethod]
        public virtual void ProductController_DeleteProductDetailsTest()
        {
            ProductDetail productDetails = ProductDetailServiceUtil.CreateProductDetailFull();
            var controller = WebHelper.GetMockedController(IoCFactory.Resolve<ProductController>());

            controller.DeleteProductDetails(productDetails.Id, productDetails.Product.Id);

            Assert.AreEqual(controller.Response.StatusCode, 200);
        }

    }
}

